package br.org.acessobrasil.portal.facade;

import java.util.List;

import javax.persistence.Query;

import br.org.acessobrasil.portal.modelo.Menu;
import br.org.acessobrasil.facade.FacadeException;
import br.org.acessobrasil.facade.GenericFacade;
import br.org.acessobrasil.portal.modelo.ItemMenu;
import br.org.acessobrasil.portal.modelo.PadraoApresentacao;
import br.org.acessobrasil.portal.modelo.Pagina;
import br.org.acessobrasil.portal.modelo.Sitio;
import br.org.acessobrasil.portal.modelo.Usuario;
import br.org.acessobrasil.portal.persistencia.LogDao;
import br.org.acessobrasil.portal.persistencia.PaginaDaoSpring;
@SuppressWarnings("unchecked")
public class PaginaFacade extends GenericFacade<Usuario,Pagina>{
	private PadraoApresentacaoFacade padraoApresentacaoFacade;
	public void setPadraoApresentacaoFacade(PadraoApresentacaoFacade padraoApresentacaoFacade) {
		this.padraoApresentacaoFacade = padraoApresentacaoFacade;
	}
	public PadraoApresentacaoFacade getPadraoApresentacaoFacade() {
		return padraoApresentacaoFacade;
	}
	private PaginaDaoSpring paginaDao;
	private LogDao logDao; 
	public LogDao getLogDao() {
		return logDao;
	}
	
	public void setLogDao(LogDao logDao) {
		this.logDao = logDao;
	}
	
	public Pagina atualizar(Usuario usuario, Pagina pagina) throws FacadeException {
		Pagina paginaUri =paginaDao.buscarPorUri(pagina.getUri()); 
		if(paginaUri!=null && !paginaUri.getNuPagina().equals(pagina.getNuPagina())){
			throw new FacadeException("Esta URI deve ser &uacute;nica. J&aacute; est&aacute; sendo utilizada pela p&aacute;gina '"+paginaUri.getNoTitulo()+"' cod " + paginaUri.getNuPagina()+".");
		}
		Pagina retorno = super.atualizar(usuario, pagina);
		retorno.setUri(pagina.getUri());//forca a atualizacao
		logDao.addLog(usuario, "Atualizou a pagina " + pagina.getNuPagina() + " titulo " + pagina.getNoTitulo());
		return retorno;
	}

	/**
	 * Coloca a pagina como principal
	 * @param usuario usuario
	 * @param nuPagina numero da pagina
	 * @throws FacadeException
	 */
	public void alterarParaPrincipal(Usuario usuario, Long nuPagina) throws FacadeException {
		Pagina pagina = buscar(usuario, nuPagina);
		if(pagina==null){
			throw new RuntimeException();
		}
		Sitio sitio = getEntityManager().find(Sitio.class, pagina.getNuSitio());
		sitio.setNuPaginaPrincipal(pagina.getNuPagina());	
	}

	public void criar(Usuario usuario, Pagina pagina) throws FacadeException {
		if(pagina.getNuSitio()==null && pagina.getSitio()==null){
			throw new FacadeException("A pagina precisa pertencer a um s&iacute;tio");
		}
		if(pagina.getNuSitio()==null){
			if(pagina.getSitio().getNuSitio()==null){
				throw new FacadeException("A pagina precisa pertencer a um s&iacute;tio");
			}
			pagina.setNuSitio(pagina.getSitio().getNuSitio());
		}
		Pagina paginaUri =paginaDao.buscarPorUri(pagina.getUri()); 
		if(paginaUri!=null){
			throw new FacadeException("Esta URI deve ser  &uacute;nica. J&aacute; est&aacute; sendo utilizada pela p&aacute;gina "+paginaUri.getNoTitulo()+" cod " + paginaUri.getNuPagina());
		}
		super.criar(usuario, pagina);
		logDao.addLog(usuario, "Criou a pagina " + pagina.getNuPagina() + " titulo " + pagina.getNoTitulo());
	}
	
	public void criar(Usuario usuarioLogado, Pagina pagina, ItemMenu itemMenu) throws FacadeException {
		criar(usuarioLogado, pagina);
		if(itemMenu!=null && itemMenu.getNuItemMenu()!=null){
			//apontar o item de menu para esta pagina
			try{
				itemMenu = getEntityManager().find(ItemMenu.class, itemMenu.getNuItemMenu());
				itemMenu.setNuPagina(pagina.getNuPagina());
			}catch(Exception e){
				throw new FacadeException("Erro ao apontar o item de menu para esta p&aacute;gina.");
			}
		}
	}

	public void excluir(Usuario usuario, Pagina pagina) throws FacadeException {
		super.excluir(usuario, pagina);
		logDao.addLog(usuario, "Apagou a pagina " + pagina.getNuPagina() + " titulo " + pagina.getNoTitulo());
	}
	
	/**
	 * Lista todas as paginas de um sitio
	 * @param nuSitio id do sitio
	 * @return lista
	 */
	public List<Pagina> listar(Long nuSitio) {
		return getEntityManager()
			.createQuery("Select o from " + Pagina.class.getCanonicalName() + " o where o.nu_sitio=?")
			.setParameter(1,nuSitio)
			.getResultList();
	}

	/**
	 * Lista pelo item de menu
	 * @param nuSitio cod do sitio
	 * @param nuItemMenu cod do menu
	 * @return lista de paginas que p.nu_sitio=? and p.nu_item_menu_secao=?
	 */
	public List<Pagina> listarPorItemMenu(Long nuSitio, Long nuItemMenu) {
		Query q = getEntityManager().createQuery("Select p From Pagina p where p.nu_sitio=? and p.nu_item_menu_secao=? order by p.no_titulo");
		q.setParameter(1, nuSitio);
		q.setParameter(2, nuItemMenu);
		return q.getResultList();
	}

	/**
	 * Pesquisa paginas com o titulo
	 * @param nuSitio cod do sitio
	 * @param titulo parte do titulo da pagina
	 * @return lista de paginas
	 */
	public List<Pagina> pesquisarPorTitulo(Long nuSitio,String titulo) {
		Query q = getEntityManager().createQuery("Select p From Pagina p where p.nu_sitio=? and p.no_titulo like :titulo order by p.no_titulo");
		q.setParameter(1, nuSitio);
		q.setParameter("titulo","%" + titulo + "%");
		return q.getResultList();
	}

	/**
	 * Lista os itens de menu de um menu
	 * @param nuMenuPrincipal
	 * @return lista
	 */
	public List<ItemMenu> listarItemMenu(Long nuMenuPrincipal) {
		Menu menu = getEntityManager().find(Menu.class, nuMenuPrincipal);
		return menu.getListItemMenu();
	}

	/**
	 * Delega para o facade de padrao de apresentacao
	 * @param sitio site
	 * @return lista de padroes cadastrados para o sitio
	 */
	public List<PadraoApresentacao> listarPadraoApresentacao(Sitio sitio) {
		return padraoApresentacaoFacade.listar(sitio);
	}
	public ItemMenu buscarItemMenu(Long nuItemMenu) {
		return getEntityManager().find(ItemMenu.class, nuItemMenu);
	}
	public PaginaDaoSpring getPaginaDao() {
		return paginaDao;
	}
	public void setPaginaDao(PaginaDaoSpring paginaDao) {
		this.paginaDao = paginaDao;
	}
	public List<Pagina> listarPorPadraoApresentacao(Long nuSitio, Long nuPadraoApresentacao) {
		Query q = getEntityManager().createQuery("Select p From Pagina p where p.nu_sitio=? and p.nu_padrao_apresentacao=?");
		q.setParameter(1, nuSitio);
		q.setParameter(2, nuPadraoApresentacao);
		return q.getResultList();
	}
}
